
<!DOCTYPE html>
<html lang="en">
    <head><meta name="generator" content="Hexo 3.9.0">
    
        <title>FairyGUI - DrawCall优化</title>
    
        <meta charset="utf-8">
        <meta name="description" content="FairyGUI教程">
        <meta name="keywords" content="FairyGUI,FGUI,FairyGUI教程">
        
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

        <meta property="og:type" content="article">
        <meta property="og:title" content="-DrawCall优化FairyGUI">
        <meta property="og:description" content="FairyGUI教程">

        <meta name="twitter:card" content="summary">
        <meta name="twitter:title" content="DrawCall优化 — FairyGUI">
        <meta name="twitter:description" content="FairyGUI教程">

      <!--  <link href='//fonts.proxy.ustclug.org/css?family=Source+Sans+Pro:300,400,600|Roboto Mono' rel='stylesheet' type='text/css'> -->

        <!-- main page styles -->
        <link rel="stylesheet" href="/docs/css/page.css">

        <!-- this needs to be loaded before guide's inline scripts -->
        <script src="/docs/js/vue.min.js"></script>
        <script>window.PAGE_TYPE = "guide_unity"</script>
    </head>
    <body class="docs">        <div id="mobile-bar" data-bg-text="FairyGUI">
            <a class="menu-button"></a>
        </div>
        <div id="header">
  <ul id="nav">
    <li><a href="/docs/guide/" class="nav-link current">教程</a></li>
<li><a href="/docs/examples/" class="nav-link">在线示例</a></li>
<li><a href="/docs/release_notes/" class="nav-link">发行日志</a></li>
<li><a href="/" class="nav-link">首页</a></li>
  </ul>
</div>

        
            <div id="main" class="fix-sidebar">
                
                    
    <div class="sidebar">
    <ul class="main-menu">
        <li><a href="/docs/guide/" class="nav-link current">教程</a></li>
<li><a href="/docs/examples/" class="nav-link">在线示例</a></li>
<li><a href="/docs/release_notes/" class="nav-link">发行日志</a></li>
<li><a href="/" class="nav-link">首页</a></li>
    </ul>
    <div class="list">
        <ul class="menu-root">
            

	 			
	                
	                <li>
	                    <a href="/docs/guide/index.html" class="sidebar-link">导读</a>
	                </li>
	            
	
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/index.html" class="sidebar-link">编辑器使用基础</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/project_settings.html" class="sidebar-link">项目设置</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/package.html" class="sidebar-link">包</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/branch.html" class="sidebar-link">分支</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/publish.html" class="sidebar-link">发布</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/object.html" class="sidebar-link">元件</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/image.html" class="sidebar-link">图片</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/movieclip.html" class="sidebar-link">动画</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/graph.html" class="sidebar-link">图形</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/loader.html" class="sidebar-link">装载器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/text.html" class="sidebar-link">文本</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/richtext.html" class="sidebar-link">富文本</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/group.html" class="sidebar-link">组</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/component.html" class="sidebar-link">组件</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/scrollpane.html" class="sidebar-link">滚动容器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/controller.html" class="sidebar-link">控制器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/relation.html" class="sidebar-link">关联系统</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/label.html" class="sidebar-link">标签</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/button.html" class="sidebar-link">按钮</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/combobox.html" class="sidebar-link">下拉框</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/progressbar.html" class="sidebar-link">进度条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/slider.html" class="sidebar-link">滑动条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/scrollbar.html" class="sidebar-link">滚动条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/list.html" class="sidebar-link">列表</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/tree.html" class="sidebar-link">树</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/popup.html" class="sidebar-link">Popup</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/dragdrop.html" class="sidebar-link">Drag&Drop</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/window.html" class="sidebar-link">窗口系统</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/transition.html" class="sidebar-link">动效</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/adaptation.html" class="sidebar-link">适配</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/i18n.html" class="sidebar-link">多国语言</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/export.html" class="sidebar-link">导入和导出</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/preference.html" class="sidebar-link">偏好设置</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/plugin.html" class="sidebar-link">插件</a>
	                </li>
	            
	
	            
	                
	                
	                <li><h3>SDK</h3></li>
	                
	                <li>
	                    <a href="/docs/guide/sdk/laya.html" class="sidebar-link">LayaAir</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/egret.html" class="sidebar-link">Egret</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/cocos2dx.html" class="sidebar-link">Cocos2dx</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/creator.html" class="sidebar-link">Cocos Creator</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/cryengine.html" class="sidebar-link">Cry Engine</a>
	                </li>
	            

	            
	                
	                
	                <li><h3>SDK - Unity</h3></li>
	                
	                <li>
	                    <a href="/docs/guide/unity/index.html" class="sidebar-link">显示UI面板</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/transform.html" class="sidebar-link">坐标系统</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/atlas.html" class="sidebar-link">纹理集的处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/font.html" class="sidebar-link">字体的处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/input.html" class="sidebar-link">输入处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/event.html" class="sidebar-link">事件机制</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/insert3d.html" class="sidebar-link">插入模型/粒子/Spine/Canvas</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/uipainter.html" class="sidebar-link">曲面UI</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/drawcall.html" class="sidebar-link current">DrawCall优化</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/lua.html" class="sidebar-link">在Lua中使用</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/special.html" class="sidebar-link">特色功能</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/faq.html" class="sidebar-link">常见问题</a>
	                </li>
	            

            
        </ul>
    </div>
</div>


<div class="content guide_unity with-sidebar ">
    
      <h1>DrawCall优化</h1>
    
    <p>在Unity中，每次引擎准备数据并通知GPU的过程称为一次Draw Call（DC）。Draw Call次数是一项非常重要的性能指标。UI系统一般包含数量众多的物体，有效控制DC是衡量一个UI系统是否实用的关键因素，特别是在移动设备上。</p>
<p>我们先来看看NGUI是怎么做的，NGUI把UIPanel中的Widget按depth排序，然后将相同材质的Widget进行Mesh合并，例如使用相同图集的图片，或者文字。Mesh合并的优点是合并后这些Widget就只产生一个DC。但这个合并过程需要计算所有Widget坐标相对于Panel的变换，而且如果Widget行为改变，例如平移，缩放等，都会触发Mesh重新合并，这会带来一定的CPU消耗，这就需要开发者谨慎组织UI元素到各个UIPanel，并且对深度需要细致安排，否则达不到减少DC效果的同时更可能带来比较大的CPU消耗。</p>
<p>UGUI的原理大体也相似，Canvas和UIPanel是类似的，每个Canvas将优化为1个Mesh或多个SubMesh。</p>
<p>FairyGUI没有采取合并Mesh的策略，原因有：</p>
<ul>
<li>FairyGUI使用的是树状显示对象结构，各个元件之间的层次关系非常复杂；</li>
<li>FairyGUI编辑器给予用户最大的设计自由度，加上动效的引入，各个元件的状态变化都非常频繁；</li>
</ul>
<p>FairyGUI基于Unity的<code>Dynamic Batching</code>技术，提供了<code>深度调整技术</code>进行 Draw Call优化 。FairyGUI能在不改变最终显示效果的前提下，尽可能的把相同材质的物体调整到连续的RenderingOrder值上，以促使他们能够被Unity Dynamic Batching优化。Dynamic Batching是Unity提供的Draw Call Batching技术之一。如果动态物体共用着相同的材质，那么Unity会自动对这些物体进行批处理。但Dynamic Batching的一个重要的前提是这些动态物体是连续渲染的。先来看看FairyGUI中物体的渲染顺序，例如：</p>
<p><img src="../../images/2015-09-23_165230.png" alt></p>
<p>这里有4个按钮，每个按钮都是一个组件，每个组件里包含一个图片和一个文字对象。FairyGUI是树状的显示对象结构，那么他们按深度排序应该是：</p>
<p><img src="../../images/2015-09-23_1702111.png" alt></p>
<p>因为文字和图片的材质并不相同，所以每次从文字到图片都产生上下文切换，所以产生了6个DC。<br>FairyGUI的深度调整技术可以优化这种情况。观察一下，其实四个按钮之间并不相交，所以FairyGUI智能地将渲染顺序调整为：</p>
<p><img src="../../images/2015-09-23_171345.png" alt></p>
<p>因为FairyGUI使用了图集，而且动态文字也使用了相同的贴图，这样，DC就降低到了2个，达到了优化的目的。实际情况会比这个复杂很多，但FairyGUI能在不改变最终显示效果的前提下，尽可能的把相同材质的物体调整到连续的RenderingOrder值上，以促使他们能够被Unity Dynamic Batching优化。而对开发者来说，这些底层上的调整是透明的，也就是不会影响原来的显示对象层次。从效率上考虑，这种技术仅比较物体之间的显示矩形区域（一个Rect）是否相交，所以速度是非常快的，不会带来过多的CPU负荷。</p>
<p>FairyGUI提供了一个开关控制组件是否启用深度调整，它就是<code>fairyBatching</code>，例如</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">aComponent.fairyBatching = <span class="literal">true</span>;</span><br></pre></td></tr></table></figure>
<p>如果某个组件设置了fairyBatching，那么无需在子组件和孙子组件再启用fairyBatching。一般只在顶层组件打开这个功能，例如主界面，加载界面等。注意，Window这个类已经自动打开了fairyBatching，这符合我们的使用习惯，因为一般我们都是以窗口为单位安排功能的。如果界面不复杂，Draw Call本来就不高的情况下，开发者也可以忽略这个功能，从10个DC优化到8个DC并没有什么意义。<strong>永远不要在GRoot上开启fairyBatching。</strong></p>
<p>对于打开了fairyBatching的组件，当开发者自己调用SetPosition等API改变子元件或者孙子元件的位置、大小，旋转或缩放，并不会自动触发深度调整，例如一个图片原来显示在一个窗口里的顶层，你用Tween将它从原来的位置移到另外一个位置，这个图片就有可能被窗口里的其他元素遮挡。这时开发者需要手动触发深度调整，例如：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">aObject.InvalidateBatchingState();</span><br></pre></td></tr></table></figure>
<p>这个API并不需要由开启了fairyBatching的组件调用，aObject可以是任何一个内含的元件。并且你可以在任何时间调用，每帧调用也可以，只要你确认是需要。它的消耗不算大，但也不能说没有。</p>
<p>对于UI动效（Transitions），FairyGUI会在动效结束后自动调用这个API。如果动效过程中有对组件的大小或者位置进行改变，并且观察到组件的渲染顺序不正确，首先可以尝试调整动效的设计，避免出现组件之间重叠状态的改变，如果确实无法避免，那么还可以强制动效每帧都执行深度调整，例如：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">aTransition.invalidateBatchingEveryFrame = <span class="literal">true</span>;</span><br></pre></td></tr></table></figure>
<p>下载并运行Demo，可以观察fairyBatching的实际效果。例如这个Demo的首页：</p>
<p><img src="../../images/2015-09-23_180017.png" alt></p>
<p>设置了fairyBatching后由42个DC减少到了6个DC，另外，可以看到Saved by batching: 37的字样。</p>
<p><img src="../../images/2015-09-23_180207.png" alt></p>
<p><img src="../../images/2015-09-23_180119.png" alt></p>

    
    <div class="footer">
      发现错误或想贡献文档?
      <a href="https://github.com/fairygui/fairygui.github.io/tree/master/src/guide/unity/drawcall.md" target="_blank">
        在 Github 上编辑此文档!
      </a>
    </div>
</div>

                
            </div>
            <script src="/docs/js/smooth-scroll.min.js"></script>
        

        <!-- main custom script for sidebars, version selects etc. -->        
        <script src="/docs/js/css.escape.js"></script>
        <script src="/docs/js/common.js"></script>
    </body>
</html>
